﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ComponentActivator;

namespace MetaContainer.Castle
{
   /// <summary>
   /// Activator specialy crafted to handle factory methods in Castle's kernel.
   /// </summary>
   internal sealed class FactoryMethodActivator : DefaultComponentActivator
   {
      private readonly Func<string, object> _factoryMethod;

      /// <summary>
      /// Creates new activator component. Factory method delegate is extracted from model's extended properties.
      /// </summary>
      /// <param name="model">Component model instance.</param>
      /// <param name="kernel">Kernel in which method will be registered.</param>
      /// <param name="onCreation">Ignored.</param>
      /// <param name="onDestruction">Ignored.</param>
      public FactoryMethodActivator(ComponentModel model, IKernel kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction) 
         : base(model, kernel, onCreation, onDestruction)
      {
         _factoryMethod = (Func<string, object>)model.ExtendedProperties["factoryMethod"];
      }
      /// <summary>
      /// Creates new instance using the factory method.
      /// </summary>
      /// <param name="context">Resolution context.</param>
      /// <returns>Newly created instance.</returns>
      protected override object Instantiate(CreationContext context)
      {
         string key = null;
         if (context.AdditionalParameters != null)
         {
            key = (string) context.AdditionalParameters["key"];
         }
         return _factoryMethod(key);
      }
   }
}
